package com.zhms.mongotest;

import com.mongodb.Block;
import com.mongodb.MongoClient;
import com.mongodb.MongoClientURI;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;
import com.mongodb.client.gridfs.GridFSBucket;
import com.mongodb.client.gridfs.GridFSBuckets;
import com.mongodb.client.gridfs.model.GridFSFile;
import com.mongodb.client.gridfs.model.GridFSUploadOptions;
import com.mongodb.client.model.*;
import com.mongodb.client.model.geojson.Point;
import com.mongodb.client.model.geojson.Position;
import com.mongodb.client.result.DeleteResult;
import com.mongodb.client.result.UpdateResult;
import com.zhms.mongotest.bean.Address;
import com.zhms.mongotest.bean.Person;
import org.bson.*;
import org.bson.codecs.configuration.CodecRegistries;
import org.bson.codecs.configuration.CodecRegistry;
import org.bson.codecs.pojo.PojoCodecProvider;
import org.bson.types.ObjectId;

import java.io.*;
import java.lang.reflect.Array;
import java.util.Arrays;
import java.util.List;

/**
 * Hello world!
 */
public class App {


    public static void main(String[] args) {
        System.out.println("Hello World!");

//        operationData();


        MongoClientURI connectionString = new MongoClientURI("mongodb://localhost:27017");
        MongoClient mongoClient = new MongoClient(connectionString);
        MongoDatabase database = mongoClient.getDatabase("zhmstest");
        MongoCollection<Document> collection = database.getCollection("restaurants");


        Block<Document> printBlock = new Block<Document>() {

            public void apply(final Document document) {
                System.out.println(document.toJson());
            }
        };

        collection.find(Filters.text("coffee")).forEach(printBlock);


    }

    private void gridFSTest() {
        //        final GridFSBucket gridFSBucket = GridFSBuckets.create(database, "wangfiles");
//        BsonDocument bsonDocument = new BsonDocument().append("a", new BsonString("MongoDB"))
//                .append("b", new BsonArray(Arrays.asList(new BsonInt32(1), new BsonInt32(2))));
//        System.out.println(bsonDocument.toJson());


        //The id of a file uploaded to GridFS, initialize to valid file id
//        ObjectId fileId = new ObjectId("595dbe3948262619603b7ea0");
//        gridFSBucket.rename(fileId, "mongopng");

//        try{
//
//
//            FileOutputStream streamToDownloadTo = new FileOutputStream("C:\\Users\\cape\\Desktop\\20170706123418wang.png");
//            gridFSBucket.downloadToStream(fileId, streamToDownloadTo);
//            streamToDownloadTo.close();
//            System.out.println(streamToDownloadTo.toString());
//
//
//        }catch (IOException e){
//
//
//        }


//        gridFSBucket.find(Filters.eq("metadata.contentType", "image/png")).forEach(
//                new Block<GridFSFile>() {
//                    public void apply(final GridFSFile gridFSFile) {
//                        System.out.println(gridFSFile.getFilename());
//                    }
//                });


//        gridFSBucket.find().forEach(new Block<GridFSFile>() {
//            public void apply(GridFSFile gridFSFile) {
//                System.out.println(gridFSFile.getFilename());
//            }
//        });


//        try {
//            InputStream streamToUplodFrom = new FileInputStream(new File("C:\\Users\\cape\\Desktop\\20170706123418.png"));
//            // Create some custom options
//
//            GridFSUploadOptions options = new GridFSUploadOptions()
//                    .chunkSizeBytes(358400)
//                    .metadata(new Document("type", "图片"));
//
//            ObjectId filedId = gridFSBucket.uploadFromStream("mongodb-tutorial-2", streamToUplodFrom, options);
//
//
//        } catch (FileNotFoundException e) {
//            e.printStackTrace();
//        }

    }


    private void geoQuery() {
        // create 2dsphere
//        collection.createIndex(Indexes.geo2dsphere("contact.location"));

//        Point refPoint = new Point(new Position(-73.9667, 40.78));
//        collection.find(Filters.near("contact.location", refPoint,5000.0, 1000.0)).forEach(printBlock);


        //meta score
//        collection.find(Filters.text("bakery cafe"))
//                .projection(Projections.metaTextScore("score"))
//                .sort(Sorts.metaTextScore("score")).forEach(printBlock);


//        long matchCountEnglish = collection.count(Filters.text("cafe", new TextSearchOptions().language("english")));
//        System.out.println("Text search matches (english): " + matchCountEnglish);


        // text search
//        long matchCount = collection.count(Filters.text("Hot"));
//        System.out.println("Text search mathches: " + matchCount);


        //create name index
//        collection.createIndex(Indexes.text("name"));
//        collection.createIndex(Indexes.ascending("stars"));


//        collection.find().projection(Projections.fields(
//                Projections.include("name"),
//                Projections.excludeId(),
//                Projections.include("stars")
//        )).forEach(printBlock);


//        collection.aggregate(
//                Arrays.asList(Aggregates.project(
//                        Projections.fields(
//                                Projections.excludeId(),
//                                Projections.include("name"),
//                                Projections.include("stars"),
//                                Projections.computed("firstCategory",
//                                        new Document("$arrayElemAt", Arrays.asList("$categories", 0)))
//                        )
//                ))
//        ).forEach(printBlock);


//        collection.aggregate(
//                Arrays.asList(
//                        Aggregates.match(Filters.eq("categories", "Bakery")),
//                        Aggregates.group("$stars", Accumulators.sum("count", 1))
//                )
//        ).forEach(printBlock);

    }


    private static void operationData() {
        MongoClientURI connectionString = new MongoClientURI("mongodb://localhost:27017");
        MongoClient mongoClient = new MongoClient(connectionString);


        CodecRegistry pojoCodecRegistry = CodecRegistries.fromRegistries(
                CodecRegistries.fromProviders(PojoCodecProvider.builder().register(Person.class, Address.class).build()),
                MongoClient.getDefaultCodecRegistry());

        MongoDatabase database = mongoClient.getDatabase("zhmstest").withCodecRegistry(pojoCodecRegistry);


        MongoCollection<Person> collection = database.getCollection("person", Person.class);

        //drop all the data in it
        collection.drop();

        // make a document and insert it
        Person ada = new Person("Ada Byron", 20, new Address("St James Square", "London", "W1"));
        collection.insertOne(ada);


        // get it (since it's the only on ein there since we dropped the rest earlier on）
        Person somebody = collection.find().first();
        System.out.println(somebody);

        // now , lets add some more people so we can explore queries and cursors
        List<Person> people = Arrays.asList(new Person("Charles Babbage", 45, new Address("5 Devonshire Street", "London", "W11")),
                new Person("Alan Turing", 28, new Address("Bletchley Hall", "Bletchley Park", "MK12")),
                new Person("Timothy Berners-Lee", 61, new Address("Colehill", "Wimborne", null)));

        collection.insertMany(people);
        System.out.println("total # of people " + collection.count());

        System.out.println("------------------------------");

        // lets get all the documents in the collection and print them out
        Block<Person> printBlock = new Block<Person>() {
            public void apply(Person person) {
                System.out.println(person);
            }
        };

        collection.find().forEach(printBlock);

        System.out.println("-------------------------------");

        // now use a query to get 1 document out

        somebody = collection.find(Filters.eq("address.city", "Wimborne")).first();
        System.out.println("----------------------------------" + somebody);


        System.out.println("-777777777777--");
        // now lets find every over 30
        collection.find(Filters.gt("age", 30)).forEach(printBlock);

        System.out.println("-------------------------------");

        // Update One
        UpdateResult updateResult = collection.updateOne(Filters.eq("name", "Ada Byron"), Updates.combine(Updates.set("age", 23), Updates.set("name", "Ada Lovelace")));


        System.out.println("==================================" + updateResult.getMatchedCount());

        // delete One
        DeleteResult deleteResult = collection.deleteOne(Filters.eq("address.city", "Wimborne"));
        System.out.println(deleteResult.getDeletedCount() + "-----------");


        // release resources
        mongoClient.close();
    }


}































